package com.itheima.reggie.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.reggie.common.CustomException;
import com.itheima.reggie.common.R;
import com.itheima.reggie.dto.DishDto;
import com.itheima.reggie.entity.Category;
import com.itheima.reggie.entity.Dish;
import com.itheima.reggie.entity.DishFlavor;
import com.itheima.reggie.service.CategoryService;
import com.itheima.reggie.service.DishFlavorService;
import com.itheima.reggie.service.DishService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * @author jay
 */
@RestController
@RequestMapping("/dish")
@Slf4j
public class DishController {
    @Autowired
    private DishService dishService;
    @Autowired
    private DishFlavorService dishFlavorService;
    @Autowired
    private CategoryService categoryService;
    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 新增菜品
     * @return
     */
    @PostMapping
    public R<String> save(@RequestBody DishDto dishDto){
        log.info("dish = {}", dishDto);
        dishService.saveWithFlavor(dishDto);
        //清理缓存
        //String key = "dish_" + dishDto.getCategoryId() + "_1"; //获取key
        //redisTemplate.delete(key);
        return R.success("添加菜品成功");
    }

    /**
     * 分页查询
     * @param page
     * @param pageSize
     * @param name
     * @return
     */
    @GetMapping("/page")
    public R<Page> page(int page, int pageSize, String name) {
        log.info("page = {},pageSize = {},name = {}",page,pageSize,name);
        Page<Dish> dishPage = new Page<>(page, pageSize);
        //前端需要菜品分类名称，Dto类里边有
        Page<DishDto> dishDtoPage = new Page<>();
        LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();
        //增加过滤条件 like,并且name是非空的情况下
        queryWrapper.like(StringUtils.isNotEmpty(name), Dish::getName, name);
        //添加排序条件
        queryWrapper.orderByDesc(Dish::getUpdateTime);
        //分页查询
        dishService.page(dishPage,queryWrapper);

        BeanUtils.copyProperties(dishPage,dishDtoPage,"records");//对象拷贝
        //dishDtoPage 需要 records => records == DishDto集合
        //            => 需要categoryName => 需要categoryId
        List<Dish> records = dishPage.getRecords(); // 拿出dishPage的records
        List<DishDto> list = new ArrayList<>();// 创建dishDto集合
        //1. 获取categoryName
        //2. 获取带有菜品名的records
        //3. 将records传入dishDtoPage，并传回前端
        for (int i = 0; i < records.size(); i++) {
            Long categoryId = records.get(i).getCategoryId(); //遍历获取categoryId
            if(categoryId == null) continue; //判断菜品是否有分类
            Category category = categoryService.getById(categoryId); //遍历获取category对象
            String categoryName = category.getName(); //遍历获取需要categoryName
            DishDto dishDto = new DishDto(); //创建DishDto
            BeanUtils.copyProperties(records.get(i),dishDto); // 数据拷贝给dishDto
            dishDto.setCategoryName(categoryName); //categoryName传入
            list.add(dishDto);//dishDto 传入 list
        }
        dishDtoPage.setRecords(list);//list 传入 dishDtoPage
        return R.success(dishDtoPage);
    }

    /**
     * 按id查询菜品信息和对应的口味信息
     * @param id
     * @return
     */
    @GetMapping("/{id}")
    public R<DishDto> getById(@PathVariable Long id){
        log.info("id = {}",id);
        DishDto dishDto = dishService.getByIdWithFlavor(id);
        return R.success(dishDto);
    }

    /**
     * 修改
     * @param dishDto
     * @return
     */
    @CacheEvict(value = "dishCache",key = "#dishDto.getCategoryId() + '_' + #dishDto.getStatus()")
    @PutMapping
    public R<String> update(@RequestBody DishDto dishDto){
        log.info("dishDto = {}",dishDto);
        dishService.updateWithFlavor(dishDto);
        //清理缓存
        //String key = "dish_" + dishDto.getCategoryId() + "_1"; //获取key
        //redisTemplate.delete(key);
        return R.success("修改菜品成功");
    }

    /**
     * 删除
     * @param ids
     * @return
     */
    @CacheEvict(value = "dishCache", allEntries = true)
    @DeleteMapping
    public R<String> delete(Long[] ids){
        log.info("ids = {}",ids);
        List<Long> dishIds = new ArrayList<>(Arrays.asList(ids));//Long数组转化为 list集合
        //判断是否是停售状态
        LambdaQueryWrapper<Dish> dishWrapper = new LambdaQueryWrapper<>();
        dishWrapper.in(Dish::getId,dishIds);
        dishWrapper.eq(Dish::getStatus, 1);
        int count = dishService.count(dishWrapper);
        if(count > 0){
            throw new CustomException("菜品售卖中，不能删除");
        }
        //删除
        dishService.removeByIds(dishIds);
        //清理菜品所有缓存
//        Set keys = redisTemplate.keys("dish_*");
//        redisTemplate.delete(keys);
        return R.success("删除成功");
    }

    /**
     * 修改状态
     * @param ids
     * @return
     */
    @CacheEvict(value = "dishCache", allEntries = true)
    @PostMapping("/status/{status}")
    public R<String> update(Long[] ids,@PathVariable int status){
        log.info("ids = {}, status = {}", ids, status);
        LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(Dish::getId,ids); //条件遍历过滤 ids
        List<Dish> list = dishService.list(queryWrapper); //拿出集合赋值status
        for (int i = 0; i < list.size(); i++) {
            list.get(i).setStatus(status);
        }
        dishService.updateBatchById(list);
        //清理菜品所有缓存
//        Set keys = redisTemplate.keys("dish_*");
//        redisTemplate.delete(keys);
        return R.success("状态修改成功");
    }

    /**
     * 根据条件查询对应的菜品数据
     * @return
     */
    @Cacheable(value = "dishCache", key = "#dish.getCategoryId() + '_' + #dish.getStatus()",
            unless = "#result == null" )
    @GetMapping("/list")
    public R<List<DishDto>> list(Dish dish){
        log.info("dish = {}", dish);
        //创建list存放dish
        List<DishDto> dishDtos = null;
        //动态创建redis的key
        //String key = "dish_" + dish.getCategoryId() + "_" + dish.getStatus(); //dish_xxx_1
        //获取key
        //dishDtos = (List<DishDto>) redisTemplate.opsForValue().get(key);
        //判断是否存在redis
        //if(dishDtos != null){
            //存在,直接返回
            //return R.success(dishDtos);
        //}

        LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();
        //条件过滤，categoryId过滤
        queryWrapper.eq(dish.getCategoryId() != null, Dish::getCategoryId, dish.getCategoryId());
        //name过滤
        queryWrapper.like(dish.getName() != null, Dish::getName, dish.getName());
        //状态过滤
        queryWrapper.eq(Dish::getStatus, 1);
        //添加排序条件
        queryWrapper.orderByAsc(Dish::getSort).orderByDesc(Dish::getUpdateTime);

        List<Dish> list = dishService.list(queryWrapper);

        //2. 增加口味数据，返回list<DishDto>
        dishDtos = new ArrayList<>();
        //查找DishFlavor并传入dishDtos
        for (int i = 0; i < list.size(); i++) {
            DishDto dishDto = new DishDto();
            BeanUtils.copyProperties(list.get(i), dishDto);//数据拷贝
            //口味传入
            LambdaQueryWrapper<DishFlavor> dishFlavorWrapper = new LambdaQueryWrapper<>();
            dishFlavorWrapper.eq(DishFlavor::getDishId,list.get(i).getId());
            List<DishFlavor> dishFlavors = dishFlavorService.list(dishFlavorWrapper);//查出口味集合
            dishDto.setFlavors(dishFlavors);
            //传入list<DishDto>
            dishDtos.add(dishDto);
        }
        //redis不存在，则将查询到的菜品数据缓存到redis
        //redisTemplate.opsForValue().set(key,dishDtos,60, TimeUnit.MINUTES);
        return R.success(dishDtos);
    }
}
